/**
 * $Revision$
 * $Date$
 *
 * Copyright 2003-2007 Jive Software.
 *
 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jivesoftware.smackx.workgroup.ext.macros;

import java.io.StringReader;

import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.StringUtils;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlPullParser;

/**
 * Macros iq is responsible for handling global and personal macros in the a
 * Live Assistant Workgroup.
 */
public class Macros extends IQ {

	private MacroGroup rootGroup;
	private boolean personal;
	private MacroGroup personalMacroGroup;

	public MacroGroup getRootGroup() {
		return rootGroup;
	}

	public void setRootGroup(MacroGroup rootGroup) {
		this.rootGroup = rootGroup;
	}

	public boolean isPersonal() {
		return personal;
	}

	public void setPersonal(boolean personal) {
		this.personal = personal;
	}

	public MacroGroup getPersonalMacroGroup() {
		return personalMacroGroup;
	}

	public void setPersonalMacroGroup(MacroGroup personalMacroGroup) {
		this.personalMacroGroup = personalMacroGroup;
	}

	/**
	 * Element name of the packet extension.
	 */
	public static final String ELEMENT_NAME = "macros";

	/**
	 * Namespace of the packet extension.
	 */
	public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup";

	public String getChildElementXML() {
		StringBuilder buf = new StringBuilder();

		buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"")
				.append(NAMESPACE).append("\">");
		if (isPersonal()) {
			buf.append("<personal>true</personal>");
		}
		if (getPersonalMacroGroup() != null) {
			buf.append("<personalMacro>");
			buf.append(StringUtils
					.escapeForXML(getPersonalMacroGroup().toXML()));
			buf.append("</personalMacro>");
		}
		buf.append("</").append(ELEMENT_NAME).append("> ");

		return buf.toString();
	}

	/**
	 * An IQProvider for Macro packets.
	 * 
	 * @author Derek DeMoro
	 */
	public static class InternalProvider implements IQProvider {

		public InternalProvider() {
			super();
		}

		public IQ parseIQ(XmlPullParser parser) throws Exception {
			Macros macroGroup = new Macros();

			boolean done = false;
			while (!done) {
				int eventType = parser.next();
				if (eventType == XmlPullParser.START_TAG) {
					if (parser.getName().equals("model")) {
						String macros = parser.nextText();
						MacroGroup group = parseMacroGroups(macros);
						macroGroup.setRootGroup(group);
					}
				} else if (eventType == XmlPullParser.END_TAG) {
					if (parser.getName().equals(ELEMENT_NAME)) {
						done = true;
					}
				}
			}

			return macroGroup;
		}

		public Macro parseMacro(XmlPullParser parser) throws Exception {
			Macro macro = new Macro();
			boolean done = false;
			while (!done) {
				int eventType = parser.next();
				if (eventType == XmlPullParser.START_TAG) {
					if (parser.getName().equals("title")) {
						parser.next();
						macro.setTitle(parser.getText());
					} else if (parser.getName().equals("description")) {
						macro.setDescription(parser.nextText());
					} else if (parser.getName().equals("response")) {
						macro.setResponse(parser.nextText());
					} else if (parser.getName().equals("type")) {
						macro.setType(Integer.valueOf(parser.nextText())
								.intValue());
					}
				} else if (eventType == XmlPullParser.END_TAG) {
					if (parser.getName().equals("macro")) {
						done = true;
					}
				}
			}
			return macro;
		}

		public MacroGroup parseMacroGroup(XmlPullParser parser)
				throws Exception {
			MacroGroup group = new MacroGroup();

			boolean done = false;
			while (!done) {
				int eventType = parser.next();
				if (eventType == XmlPullParser.START_TAG) {
					if (parser.getName().equals("macrogroup")) {
						group.addMacroGroup(parseMacroGroup(parser));
					}
					if (parser.getName().equals("title")) {
						group.setTitle(parser.nextText());
					}
					if (parser.getName().equals("macro")) {
						group.addMacro(parseMacro(parser));
					}
				} else if (eventType == XmlPullParser.END_TAG) {
					if (parser.getName().equals("macrogroup")) {
						done = true;
					}
				}
			}
			return group;
		}

		public MacroGroup parseMacroGroups(String macros) throws Exception {

			MacroGroup group = null;
			XmlPullParser parser = XmlPullParserFactory.newInstance()
					.newPullParser();
			parser.setInput(new StringReader(macros));
			int eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				eventType = parser.next();
				if (eventType == XmlPullParser.START_TAG) {
					if (parser.getName().equals("macrogroup")) {
						group = parseMacroGroup(parser);
					}
				}
			}
			return group;
		}
	}
}